package xyz.hlh.boot3.aspect;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author HLH
 * @description Service 日志打印
 * @email 17703595860@163.com
 * @date Created in 2021/8/7 上午11:25
 */
@Component // 注册组件
@Aspect // 开启aop
@Slf4j(topic = "service") // 修改logger name
public class ServiceLogAspect {

    /**
     * 拦截所有service中的所有方法
     */
    @Pointcut(value = "execution(* xyz.hlh.boot3..service..*(..))")
    public void pointCut() {}

    /**
     * 前置打印
     */
    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法名
        String methodName = signature.getName();
        // 获取类全限定类名
        String declaringTypeName = signature.getDeclaringTypeName();
        // 获取类名
        String className = declaringTypeName.substring(declaringTypeName.lastIndexOf(".") + 1);
        // 记录日志
        Object[] args = joinPoint.getArgs();
        log.info("{}.{} is called, args list is {}", className, methodName, JSONUtil.toJsonStr(args));
    }

    /**
     * 后置打印
     */
    @AfterReturning(value = "pointCut()", returning = "returnObj")
    public void afterReturning(JoinPoint joinPoint, Object returnObj) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法名
        String methodName = signature.getName();
        // 获取类全限定类名
        String declaringTypeName = signature.getDeclaringTypeName();
        // 获取类名
        String className = declaringTypeName.substring(declaringTypeName.lastIndexOf(".") + 1);
        // 记录日志
        log.info("{}.{} is call to complete, return value is {}", className, methodName, JSONUtil.toJsonStr(returnObj));
    }

    /**
     * 异常打印
     */
    @AfterThrowing(value = "pointCut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法名
        String methodName = signature.getName();
        // 获取类全限定类名
        String declaringTypeName = signature.getDeclaringTypeName();
        // 获取类名
        String className = declaringTypeName.substring(declaringTypeName.lastIndexOf(".") + 1);
        // 记录日志
        log.error("{}.{} throws exception '{}' because of '{}'"
                , className, methodName, e.getClass(), e.getMessage(), e);
    }

}
